package cn.openread.starter.utils;

import cn.openread.starter.utils.exception.QRgenException;
import cn.openread.starter.utils.qrcode.QRCodeFactory;
import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.HybridBinarizer;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.UUID;

import static jodd.util.StringPool.UTF_8;

/**
 * 提供生成二维码服务
 *
 * @author simon
 * @create 2018-09-07 下午5:23
 **/
@Slf4j
@NoArgsConstructor
public class QrCodeStarter {
    private static volatile QrCodeStarter instance = null;

    public static QrCodeStarter getInstance() {
        if (instance == null) {
            synchronized (QrCodeStarter.class) {
                if (instance == null) {
                    instance = new QrCodeStarter();
                }
            }
        }
        return instance;
    }

    /**
     * @param content    文本内容
     * @param outFileUri 生成的二维码存储地址,(如果是空，将返回文件流)
     * @param height     二维码的高度
     * @param width      二维码的宽度
     * @param logoUrl    二维码的中心logo的http访问地址(如果是空,将采用默认的logo)
     * @return 返回文件byte[]流
     */
    public byte[] generate(String content, String outFileUri, String logoUrl, Integer width, Integer height) {
        if (StringUtils.isBlank(content)) {
            throw new QRgenException("生成二维码，缺少content参数");
        }
        if (width == null || width < 20) {
            throw new QRgenException("生成二维码，width参数,错误,width > 20");
        }
        if (height == null || height < 20) {
            throw new QRgenException("生成二维码，height参数,错误,height > 20");
        }
        if (StringUtils.isBlank(outFileUri)) {
            outFileUri = System.getProperty("java.io.tmpdir") + File.separator + UUID.randomUUID().toString();
        }

        int[] size = new int[]{width, height};
        String format = "png";
        try {
            return QRCodeFactory.creatQrImage(content, format, outFileUri, logoUrl, size);
        } catch (IOException | WriterException e) {
            log.error(e.getMessage(), e);
            return null;
        }
    }

    /**
     * 读取二维码
     *
     * @param qrCode 二维码类型可以是File=文件，URL=网络文件
     */
    public String read(Object qrCode) {
        try {
            MultiFormatReader formatReader = new MultiFormatReader();
            BufferedImage image = null;

            if (qrCode instanceof File) {
                image = ImageIO.read((File) qrCode);
            } else if (qrCode instanceof URL) {
                image = ImageIO.read((URL) qrCode);
            }

            if (qrCode == null) {
                throw new QRgenException("读取二维码，qrCode参数,qrCode is null");
            }

            BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(
                    new BufferedImageLuminanceSource(image)));

            HashMap hints = new HashMap();
            // 字符集
            hints.put(EncodeHintType.CHARACTER_SET, UTF_8);

            Result result = formatReader.decode(binaryBitmap, hints);

            log.debug("解析之后的结果:" + result.toString());
            log.debug("二维码格式类型:" + result.getBarcodeFormat());
            log.debug("二维码文本内容:" + result.getText());
            return result.getText();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return null;
        }
    }
}
